//
// Created by 张祎鹤严 on 2022/12/12.
//

#include "bsp_iic.h"

uint16_t sda;
//产生IIC起始信号

void Delay_us(void)
{
    __IO uint16_t i = 10;
    while(i--){}
}

void IIC_Start(void)
{
    IIC_SDA_H;
    IIC_SCL_H;
    Delay_us();
    IIC_SDA_L;//START:when CLK is high,DATA change form high to low
    Delay_us();
    IIC_SCL_L;//钳住I2C总线，准备发送或接收数据
    Delay_us();
}
//产生IIC停止信号
void IIC_Stop(void)
{
    IIC_SDA_L;
    Delay_us();
    IIC_SCL_H;
    Delay_us();
    IIC_SDA_H;
    Delay_us();
}
//等待应答信号到来
//返回值：1，接收应答失败
//        0，接收应答成功
uint8_t IIC_Wait_Ack(void)
{
    uint16_t ucErrTime=0;
    IIC_SDA_H; Delay_us();
    IIC_SCL_H; Delay_us();
    while(SDA_READ){
        ucErrTime ++;
        if(ucErrTime > 2500){
            IIC_Stop();
            return 1;
        }
    }
    IIC_SCL_L;//时钟输出0
    return 0;
}
//产生ACK应答
void IIC_Ack(void)
{
    IIC_SDA_L;
    Delay_us();
    IIC_SCL_H;
    Delay_us();
    IIC_SCL_L;
    Delay_us();
    IIC_SDA_H;
}
//不产生ACK应答
void IIC_NAck(void)
{
    IIC_SDA_H;
    Delay_us();
    IIC_SCL_H;
    Delay_us();
    IIC_SCL_L;
    Delay_us();
    IIC_SDA_L;
}
//IIC发送一个字节
//返回从机有无应答
//1，有应答
//0，无应答
void IIC_Send_Byte(uint8_t txd)
{
    uint8_t t;
    IIC_SCL_L;//拉低时钟开始数据传输
    for(t = 0;t < 8; t++)
    {
        if(txd & 0x80)
            IIC_SDA_H;
        else
            IIC_SDA_L;
        txd <<= 1;
        IIC_SCL_H;
        Delay_us();
        IIC_SCL_L;
        Delay_us();
        /*if(t == 7)
            IIC_SDA_H;
        Delay_us();*/

        /*IIC_SDA = (txd & 0x80)>>7;
        txd <<= 1;
        Delay_us();
        IIC_SCL = 1;
        Delay_us();
        IIC_SCL = 0;
        Delay_us();*/
    }
}
//读1个字节，ack=1时，发送ACK，ack=0，发送nACK
uint8_t IIC_Read_Byte(unsigned char ack)
{
    uint8_t i, receive = 0;
    for(i = 0; i < 8; i++)
    {
        IIC_SCL_H;
        Delay_us();
        receive <<= 1;
        if(SDA_READ)
            receive |= 0x01;
        IIC_SCL_L;
        Delay_us();

        /*IIC_SCL = 0;
        Delay_us();
        IIC_SCL = 1;
        receive <<= 1;
        if(IIC_SDA) receive++;
        Delay_us();*/
    }
    if (!ack)
        IIC_NAck();//发送nACK
    else
        IIC_Ack(); //发送ACK
    return receive;
}
